unit UnitVP;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, Math;

const
  N = 19;
  PW = 30;
  PH = 30;
  DH = 10;

type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    Label1: TLabel;
    Timer1: TTimer;
    Timer2: TTimer;
    Timer3: TTimer;
    procedure BitBtn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer3Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DrawHeap;
  end;

var
  Form1: TForm1;
  nn, k, l, x, y, x0, y0, it1, it3: Integer;
  pan: array of TPanel;
  mass: array of Integer;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  i: Integer;
begin
  it1:=N;
  nn:=N;
  Randomize;
  for i:=0 to N-1 do
  begin
    mass[i]:=Random(50);
  end;
  DrawHeap;
  Label1.Caption:='Your massive was: ';
  for i:=0 to N-1 do
  begin
    Label1.Caption:=Label1.Caption + IntToStr(mass[i]) + ' ';
  end;
  Timer1.Enabled:=True;
end;

procedure TForm1.DrawHeap;
var
  i, j, ii, m, d: Integer;
begin
  ii:=N-1;
  Randomize;
  for i:=0 to N-1 do
  begin
    mass[i]:=Random(50);
  end;
  for i:=0 to N-1 do
  begin
    pan[i]:=TPanel.Create(Form1);
    pan[i].Width:=PW;
    pan[i].Height:=PH;
    pan[i].Parent:=Form1;
  end;
  k:=Floor(Log2(N));
  d:=PW div 4;
  l:= N - (Floor(Power (2, k)) - 1);
  m:=k-1;
  x0:= 50 + (l-1)*(PW+d);
  y0:= k*(PH+DH) + 200;
  x:=x0;
  y:=y0;
  for i:= 1 to k+1 do
  begin
    if i = 1 then
    begin
      for j:= 1 to l do
      begin
        pan[ii].Left:=x;
        pan[ii].Top:=y;
        pan[ii].Caption:=IntToStr(mass[ii]);
        x:= x - PW - d;
        Dec(ii);
      end;
      x0:=x0 + (Floor(Power(2, k)) - l)*(PW + d);
      y:=y0;
    end else begin
      x0:= x0 - (d div 2) - (PW div 2);
      x:=x0;
      d:=d + 2*PW - (PW-d);
      y:= y - PH - DH;
      for j:= 1 to Floor(Power(2, m)) do
      begin
        pan[ii].Left:=x;
        pan[ii].Top:=y;
        pan[ii].Caption:=IntToStr(mass[ii]);
        x:=x - PW - d;
        Dec(ii);
      end;
      Dec(m);
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i:Integer;
begin
  SetLength(mass, N);
  SetLength(pan, N);
  for i:=0 to N-1 do
  begin
    pan[i]:=TPanel.Create(Form1);
    pan[i].Width:=PW;
    pan[i].Height:=PH;
    pan[i].Parent:=Form1;
  end;
end;

procedure TForm1.Timer3Timer(Sender: TObject);
var
  a, b, k, i: Integer;
  kp: string;
begin
  for i:=0 to nn-1 do
  begin
    pan[i].Color:=clBtnFace;
  end;
  if nn < N then
  begin
    pan[nn].Color:=clLime;
  end;
  a:=2000000000;
  b:=2000000000;
  pan[it3].Color:=clYellow;
  if (2*it3 + 1 < nn) then
  begin
    a:=mass[2*it3 + 1];
    pan[2*it3 + 1].Color:=clYellow;
  end;
  if (2*it3 + 2 < nn) then
  begin
    b:=mass[2*it3 + 2];
    pan[2*it3 + 2].Color:=clYellow;
  end;
  if (a <= b) and (a < mass[it3]) then
  begin
    pan[it3].Color:=clRed;
    pan[2*it3 + 1].Color:=clRed;

    kp:=pan[it3].Caption;
    pan[it3].Caption:=pan[2*it3+1].Caption;
    pan[2*it3+1].Caption:=kp;

    k:=mass[it3];
    mass[it3]:=mass[2*it3+1];
    mass[2*it3+1]:=k;

    it3:=2*it3+1;
  end else if (b <= a) and (b < mass[it3]) then
  begin
    pan[it3].Color:=clRed;
    pan[2*it3 + 2].Color:=clRed;

    kp:=pan[it3].Caption;
    pan[it3].Caption:=pan[2*it3+2].Caption;
    pan[2*it3+2].Caption:=kp;

    k:=mass[it3];
    mass[it3]:=mass[2*it3+2];
    mass[2*it3+2]:=k;

    it3:=2*it3+2;
  end else begin
    Timer3.Enabled:=False;
    Timer1.Enabled:=True;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Dec(it1);
  Timer1.Enabled:=False;
  if it1 >= 0 then
  begin
    it3:=it1;
    Timer3.Enabled:=True;
  end else begin
    Timer2.Enabled:=True;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var
  k2, i: Integer;
  kp2: string;
begin
  Dec(nn);
  if nn > 0 then
  begin
    for i:=0 to nn do
    begin
      pan[i].Color:=clBtnFace;
    end;

    k2:= mass[0];
    mass[0]:= mass[nn];
    mass[nn]:=k2;

    pan[0].Color:=clTeal;
    pan[nn].Color:=clTeal;

    kp2:= pan[0].Caption;
    pan[0].Caption:= pan[nn].Caption;
    pan[nn].Caption:=kp2;

    it3:=0;
    Timer3.Enabled:=True;
    Timer2.Enabled:=False;

    if nn < N-1 then
      pan[nn+1].Color:=clLime;
  end else begin
    Label1.Caption:=Label1.Caption + #13 + 'Sorted massive is: ';
    for i:=0 to N-1 do
    begin
      Label1.Caption:=Label1.Caption + IntToStr(mass[i]) + ' ';
    end;
    pan[0].Color:=clLime;
    Timer2.Enabled:=False;
  end;
end;

end.
